<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>modmatrix</title>
    <link rel="stylesheet" type="text/css" href="csound.css" />
    <meta name="generator" content="DocBook XSL Stylesheets V1.78.1" />
    <link rel="home" href="index.html" title="The Canonical Csound Reference Manual" />
    <link rel="up" href="OpcodesTop.html" title="Orchestra Opcodes and Operators" />
    <link rel="prev" href="mode.html" title="mode" />
    <link rel="next" href="monitor.html" title="monitor" />
  </head>
  <body>
    <div class="navheader">
      <table width="100%" summary="Navigation header">
        <tr>
          <th colspan="3" align="center">modmatrix</th>
        </tr>
        <tr>
          <td width="20%" align="left"><a accesskey="p" href="mode.html">Prev</a> </td>
          <th width="60%" align="center">Orchestra Opcodes and Operators</th>
          <td width="20%" align="right"> <a accesskey="n" href="monitor.html">Next</a></td>
        </tr>
      </table>
      <hr />
    </div>
    <div class="refentry">
      <a id="modmatrix"></a>
      <div class="titlepage"></div>
      <a id="IndexModmatrix" class="indexterm"></a>
      <div class="refnamediv">
        <h2>
          <span class="refentrytitle">modmatrix</span>
        </h2>
        <p>modmatrix — 
      Modulation matrix opcode with optimizations for sparse matrices.
    </p>
      </div>
      <div class="refsect1">
        <a id="idp126039680"></a>
        <h2>Description</h2>
        <p>
      The opcode can be used to let a large number of k-rate modulator
      variables modulate a large number of k-rate parameter variables,
      with arbitrary scaling of each modulator-to-parameter
      connection.  Csound ftables are used to hold both the input
      (parameter)  variables, the modulator variables, and the scaling
      coefficients. Output variables are written to another Csound ftable.
    </p>
      </div>
      <div class="refsect1">
        <a id="idp126043904"></a>
        <h2>Syntax</h2>
        <pre class="synopsis"><span class="command"><strong>modmatrix</strong></span> iresfn, isrcmodfn, isrcparmfn, imodscale, inum_mod, \\
inum_parm, kupdate</pre>
      </div>
      <div class="refsect1">
        <a id="idp126046016"></a>
        <h2>Initialization</h2>
        <p>
      <span class="emphasis"><em>iresfn</em></span> --  ftable number for the parameter output variables
    </p>
        <p>
      <span class="emphasis"><em>isrcmodfn</em></span> -- ftable number for the modulation source variables
    </p>
        <p>
      <span class="emphasis"><em>isrcparmfn</em></span> -- ftable number for the parameter input variables
    </p>
        <p>
      <span class="emphasis"><em>imodscale</em></span> -- scaling/routing coefficient
      matrix. This is also a csound ftable, used as a matrix of
      inum_mod rows and inum_parm columns.
    </p>
        <p>
      <span class="emphasis"><em>inum_mod</em></span> -- number of modulation variables
    </p>
        <p>
      <span class="emphasis"><em>inum_parm</em></span> -- number of parmeter (input and
      output) variables.
    </p>
        <p>
    The arguments <span class="emphasis"><em>inum_mod</em></span>
    and <span class="emphasis"><em>inum_parm</em></span> do not have to be set to
    power-of-two values.
    </p>
      </div>
      <div class="refsect1">
        <a id="idp126119424"></a>
        <h2>Performance</h2>
        <p>
      <span class="emphasis"><em>kupdate</em></span> -- flag to update the scaling
      coefficients. When the flag is set to a nonzero value, the
      scaling coefficients are read directly from the imodscale
      ftable. When the flag is set to zero, the scaling coefficients
      are scanned, and an optimized scaling matrix stored internally
      in the opcode.
    </p>
        <p>
      For each modulator in <span class="emphasis"><em>isrcmodfn</em></span>, scale it
      with the coefficient (in <span class="emphasis"><em>imodscale</em></span>)
      determining to what degree it should influence each
      parameter. Then sum all modulators for each parameter and add
      the resulting modulator value to the input parameter value read from
      <span class="emphasis"><em>iscparmfn</em></span>. Finally, write the output
      parameter values to table <span class="emphasis"><em>iresfn</em></span>.
    </p>
        <p>
      The following tables give insight into the processing performed
      by the modmatrix opcode, for a simplified example using 3
      parameter and 2 modulators. Let’s call the parameters
      "cps1", "cps2", and "cutoff", and
      the modulators "lfo1" and "lfo2".
    </p>
        <p>
      The input variables may at a given point in time have these
      values:
  </p>
        <div class="table">
          <a id="modmatrix-table1"></a>
          <p class="title">
            <strong>Table 12. </strong>
          </p>
          <div class="table-contents">
            <table border="1">
              <colgroup>
                <col />
                <col />
                <col />
                <col />
              </colgroup>
              <thead>
                <tr>
                  <th> </th>
                  <th>cps1</th>
                  <th>cps2</th>
                  <th>cutoff</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td>
                    <span class="emphasis">
                      <em>isrcparmfn</em>
                    </span>
                  </td>
                  <td>400</td>
                  <td>800</td>
                  <td>3</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
        <p><br class="table-break" />
    </p>
        <p>
    </p>
        <p>
      ... while the modulator variables have these values:
  </p>
        <div class="table">
          <a id="modmatrix-table2"></a>
          <p class="title">
            <strong>Table 13. </strong>
          </p>
          <div class="table-contents">
            <table border="1">
              <colgroup>
                <col />
                <col />
                <col />
              </colgroup>
              <thead>
                <tr>
                  <th> </th>
                  <th>lfo1</th>
                  <th>lfo2</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td>
                    <span class="emphasis">
                      <em>isrcmodfn</em>
                    </span>
                  </td>
                  <td>0.5</td>
                  <td>-0.2</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
        <p><br class="table-break" />
    </p>
        <p>
      The scaling/routing coefficients used:
  </p>
        <div class="table">
          <a id="modmatrix-table3"></a>
          <p class="title">
            <strong>Table 14. </strong>
          </p>
          <div class="table-contents">
            <table border="1">
              <colgroup>
                <col />
                <col />
                <col />
                <col />
              </colgroup>
              <thead>
                <tr>
                  <th>
                    <span class="emphasis">
                      <em>imodscale</em>
                    </span>
                  </th>
                  <th>cps1</th>
                  <th>cps2</th>
                  <th>cutoff</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td>
                    <span class="emphasis">
                      <em>lfo1</em>
                    </span>
                  </td>
                  <td>40</td>
                  <td>0</td>
                  <td>-2</td>
                </tr>
                <tr>
                  <td>
                    <span class="emphasis">
                      <em>lfo2</em>
                    </span>
                  </td>
                  <td>-50</td>
                  <td>100</td>
                  <td>3</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
        <p><br class="table-break" />
    </p>
        <p>
      ... and the resulting output values:
  </p>
        <div class="table">
          <a id="modmatrix-table4"></a>
          <p class="title">
            <strong>Table 15. </strong>
          </p>
          <div class="table-contents">
            <table border="1">
              <colgroup>
                <col />
                <col />
                <col />
                <col />
              </colgroup>
              <thead>
                <tr>
                  <th> </th>
                  <th>cps1</th>
                  <th>cps2</th>
                  <th>cutoff</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td>
                    <span class="emphasis">
                      <em>iresfn</em>
                    </span>
                  </td>
                  <td>430</td>
                  <td>780</td>
                  <td>1.4</td>
                </tr>
                <tr>
                  <td>
                    <span class="emphasis">
                      <em>lfo2</em>
                    </span>
                  </td>
                  <td>-50</td>
                  <td>100</td>
                  <td>3</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
        <p><br class="table-break" />
    </p>
        <p> 
      The output value for "cps1" is calculated as
      400+(0.5*40)+(-0.2*-50), similarly for "cps2"
      800+(0.5*0)+(-0.2*100), and for cutoff: 3+(0.5*-2)+(-0.2*3) 
    </p>
        <p>
      The imodscale ftable may be specified in the score like this:
      </p>
        <pre class="programlisting">f1  0  8  -2  200 0 2 50 300 -1.5</pre>
        <p> 
    </p>
        <p>
       Or more conveniently using <a class="link" href="ftgen.html" title="ftgen"><em class="citetitle">ftgen</em></a> in the orchestra:
      </p>
        <pre class="programlisting">gimodscale ftgen 0, 0, 8, -2, 200, 0, 2, 50, 300, -1.5</pre>
        <p> 
    </p>
        <p>
      Obviously, the parameter and modulator variables need not be
      static values, and similarly, the scaling routing coefficient
      table may be continuously rewritten using opcodes
      like <a class="link" href="tablew.html" title="tablew"><em class="citetitle">tablew</em></a>. 
    </p>
      </div>
      <div class="refsect1">
        <a id="idp126163200"></a>
        <h2>Examples</h2>
        <p>
      Here is an example of the modmatrix opcode. It uses the file <a class="ulink" href="examples/modmatrix.csd" target="_top"><em class="citetitle">modmatrix.csd</em></a>.
      </p>
        <div class="example">
          <a id="idp126165056"></a>
          <p class="title">
            <strong>Example 522. Example of the modmatrix opcode.</strong>
          </p>
          <div class="example-contents">
            <p>See the sections <a class="link" href="UsingRealTime.html" title="Real-Time Audio"><em class="citetitle">Real-time Audio</em></a> and <a class="link" href="CommandFlags.html" title="Csound command line"><em class="citetitle">Command Line Flags</em></a> for more information on using command line flags.</p>
            <pre class="programlisting">
<span class="csdtag">&lt;CsoundSynthesizer&gt;</span>
<span class="csdtag">&lt;CsOptions&gt;</span>
<span class="comment">; Select audio flags here according to platform</span>
<span class="comment">; Audio out   Audio in</span>
<span class="comment">;-odac           -iadc    ;;;RT audio I/O</span>
<span class="comment">; For Non-realtime ouput leave only the line below:</span>
 -o modmatrix.wav -W <span class="comment">;;; for file output any platform</span>
<span class="csdtag">&lt;/CsOptions&gt;</span>
<span class="csdtag">&lt;CsInstruments&gt;</span>

	<span class="ohdr">sr</span>	<span class="op">=</span>	44100
	<span class="ohdr">kr</span>	<span class="op">=</span>	441
	<span class="ohdr">ksmps</span>	<span class="op">=</span>	100
	<span class="ohdr">nchnls</span>	<span class="op">=</span>	2
	<span class="ohdr">0dbfs</span>	<span class="op">=</span> 	1

<span class="comment">; basic waveforms</span>
giSine	<span class="ohdr">ftgen</span>	0, 0, 65537, 10, 1	<span class="comment">; sine wave</span>
giSaw 	<span class="ohdr">ftgen</span>	0, 0, 4097, 7, 1, 4096, <span class="op">-</span>1	<span class="comment">; saw (linear)</span>
giSoftSaw <span class="ohdr">ftgen</span>	0, 0, 65537, 30, giSaw, 1, 10	<span class="comment">; soft saw (only 10 first harmonics)</span>

<span class="comment">; modmatrix tables</span>
giMaxNumParam	<span class="op">=</span> 128
giMaxNumMod	<span class="op">=</span> 32
giParam_In <span class="ohdr">ftgen</span> 0, 0, giMaxNumParam, 2, 0	<span class="comment">; input parameters table</span>
<span class="comment">; output parameters table (parameter values with added modulators)</span>
giParam_Out <span class="ohdr">ftgen</span> 0, 0, giMaxNumParam, 2, 0	
giModulators <span class="ohdr">ftgen</span> 0, 0, giMaxNumMod, 2, 0	 <span class="comment">; modulators table</span>
<span class="comment">; modulation scaling and routing (mod matrix) table, start with empty table</span>
giModScale <span class="ohdr">ftgen</span> 0, 0, giMaxNumParam<span class="op">*</span>giMaxNumMod, <span class="op">-</span>2, 0		

<span class="comment">;********************************************</span>
<span class="comment">; generate the modulator signals</span>
<span class="comment">;********************************************</span>
	<span class="oblock">instr</span> 1

<span class="comment">; LFO1, 1.5 Hz, normalized range (0.0 to 1.0)</span>
kLFO1	<span class="opc">oscil</span>	0.5, 1.5, giSine		<span class="comment">; generate LFO signal</span>
kLFO1	<span class="op">=</span> kLFO1<span class="op">+</span>0.5				<span class="comment">; offset</span>

<span class="comment">; LFO2, 0.4 Hz, normalized range (0.0 to 1.0)</span>
kLFO2	<span class="opc">oscil</span>	0.5, 0.4, giSine		<span class="comment">; generate LFO signal</span>
kLFO2	<span class="op">=</span> kLFO2<span class="op">+</span>0.5				<span class="comment">; offset</span>


<span class="comment">; write modulators to table</span>
	<span class="opc">tablew</span>	kLFO1, 0, giModulators
	<span class="opc">tablew</span>	kLFO2, 1, giModulators

	<span class="oblock">endin</span>

<span class="comment">;********************************************</span>
<span class="comment">; set parameter values</span>
<span class="comment">;********************************************</span>
	<span class="oblock">instr</span> 2

<span class="comment">; Here we can set the parameter values</span>
icps1	<span class="op">=</span> p4
icps2	<span class="op">=</span> p5
icutoff	<span class="op">=</span> p6
	
<span class="comment">; write parameters to table</span>
	<span class="opc">tableiw</span>	icps1, 0, giParam_In
	<span class="opc">tableiw</span>	icps2, 1, giParam_In
	<span class="opc">tableiw</span>	icutoff, 2, giParam_In

	<span class="oblock">endin</span>

<span class="comment">;********************************************</span>
<span class="comment">; mod matrix edit</span>
<span class="comment">;********************************************</span>
	<span class="oblock">instr</span> 3

<span class="comment">; Here we can write to the modmatrix table by using tablew or tableiw</span>

iLfo1ToCps1	<span class="op">=</span> p4
iLfo1ToCps2	<span class="op">=</span> p5
iLfo1ToCutoff	<span class="op">=</span> p6
iLfo2ToCps1	<span class="op">=</span> p7
iLfo2ToCps2	<span class="op">=</span> p8
iLfo2ToCutoff	<span class="op">=</span> p9

	<span class="opc">tableiw</span>	iLfo1ToCps1, 0, giModScale
	<span class="opc">tableiw</span>	iLfo1ToCps2, 1, giModScale
	<span class="opc">tableiw</span>	iLfo1ToCutoff, 2, giModScale
	<span class="opc">tableiw</span>	iLfo2ToCps1, 3, giModScale
	<span class="opc">tableiw</span>	iLfo2ToCps2, 4, giModScale
	<span class="opc">tableiw</span>	iLfo2ToCutoff, 5, giModScale
	
<span class="comment">; and set the update flag for modulator matrix </span>
<span class="comment">; ***(must update to enable changes)</span>
ktrig	<span class="opc">init</span> 1
	<span class="opc">chnset</span>	ktrig, "modulatorUpdateFlag"
ktrig	<span class="op">=</span> 0

	<span class="oblock">endin</span>

<span class="comment">;********************************************</span>
<span class="comment">; mod matrix</span>
<span class="comment">;********************************************</span>
	<span class="oblock">instr</span> 4

<span class="comment">; get the update flag</span>
kupdate	<span class="opc">chnget</span>	"modulatorUpdateFlag"		

<span class="comment">; run the mod matrix </span>
inum_mod	<span class="op">=</span> 2
inum_parm	<span class="op">=</span> 3
	<span class="opc">modmatrix</span> giParam_Out, giModulators, giParam_In, \\
	giModScale, inum_mod, inum_parm, kupdate

<span class="comment">; and reset the update flag</span>
	<span class="opc">chnset</span>	0, "modulatorUpdateFlag"  <span class="comment">; reset the update flag</span>

	<span class="oblock">endin</span>

<span class="comment">;********************************************</span>
<span class="comment">; audio generator to test values</span>
<span class="comment">;********************************************</span>
	<span class="oblock">instr</span> 5

<span class="comment">; basic parameters</span>
	iamp	<span class="op">=</span> <span class="opc">ampdbfs</span>(<span class="op">-</span>5)

<span class="comment">; read modulated parameters from table</span>
	kcps1	<span class="opc">table</span>	0, giParam_Out
	kcps2	<span class="opc">table</span>	1, giParam_Out
	kcutoff	<span class="opc">table</span>	2, giParam_Out

<span class="comment">; set filter parameters</span>
	kCF_freq1	<span class="op">=</span> kcps1<span class="op">*</span>kcutoff
	kCF_freq2	<span class="op">=</span> kcps2<span class="op">*</span>kcutoff
	kReso		<span class="op">=</span> 0.7
	kDist		<span class="op">=</span> 0.3

<span class="comment">; oscillators and filters</span>
	a1	<span class="opc">oscili</span>	iamp, kcps1, giSoftSaw
	a1	<span class="opc">lpf18</span>	a1, kCF_freq1, kReso, kDist

	a2	<span class="opc">oscili</span>	iamp, kcps2, giSoftSaw
	a2	<span class="opc">lpf18</span>	a2, kCF_freq2, kReso, kDist
	
		<span class="opc">outs</span> 	a1, a2

	<span class="oblock">endin</span>

<span class="csdtag">&lt;/CsInstruments&gt;</span>
<span class="csdtag">&lt;CsScore&gt;</span>

<span class="comment">;********************************************</span>
<span class="comment">; set initial parameters</span>
<span class="comment">;	cps1	cps2	cutoff</span>
<span class="stamnt">i</span>2 0 1	400	800	3

<span class="comment">;********************************************</span>
<span class="comment">; set modmatrix values</span>
<span class="comment">;	lfo1ToCps1 lfo1ToCps2 lfo1ToCut lfo2ToCps1 lfo2ToCps2 lfo2ToCut</span>
<span class="stamnt">i</span>3 0 1 	40         0          -2        -50        100        3

<span class="comment">;********************************************</span>
<span class="comment">; start "always on" instruments</span>
#define SCORELEN # 20 #	 <span class="comment">; set length of score</span>

<span class="stamnt">i</span>1 0 $SCORELEN			<span class="comment">; start modulators</span>
<span class="stamnt">i</span>4 0 $SCORELEN			<span class="comment">; start mod matrix</span>
<span class="stamnt">i</span>5 0 $SCORELEN			<span class="comment">; start audio oscillator</span>

<span class="stamnt">e</span>	

<span class="csdtag">&lt;/CsScore&gt;</span>
<span class="csdtag">&lt;/CsoundSynthesizer&gt;</span>
</pre>
          </div>
        </div>
        <p><br class="example-break" />
    </p>
      </div>
      <div class="refsect1">
        <a id="idp126169344"></a>
        <h2>See Also</h2>
        <p>
      <a class="link" href="linearalgebraopcodes.html" title="Linear Algebra Opcodes"><em class="citetitle">Linear Algebra
      Opcodes</em></a>, 
      <a class="link" href="vectorial.html" title="Vectorial Opcodes"><em class="citetitle">Vectorial
      Opcodes</em></a>, 
      <a class="link" href="tablew.html" title="tablew"><em class="citetitle">tablew</em></a>.
    </p>
      </div>
      <div class="refsect1">
        <a id="idp126173360"></a>
        <h2>Credits</h2>
        <p>By:</p>
        <p>Oeyvind Brandtsegg and Thom Johansen</p>
        <p>New in version 5.12</p>
      </div>
    </div>
    <div class="navfooter">
      <hr />
      <table width="100%" summary="Navigation footer">
        <tr>
          <td width="40%" align="left"><a accesskey="p" href="mode.html">Prev</a> </td>
          <td width="20%" align="center">
            <a accesskey="u" href="OpcodesTop.html">Up</a>
          </td>
          <td width="40%" align="right"> <a accesskey="n" href="monitor.html">Next</a></td>
        </tr>
        <tr>
          <td width="40%" align="left" valign="top">mode </td>
          <td width="20%" align="center">
            <a accesskey="h" href="index.html">Home</a>
          </td>
          <td width="40%" align="right" valign="top"> monitor</td>
        </tr>
      </table>
    </div>
  </body>
</html>
